﻿using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;

namespace placinfo
{
    [DataContract]
    public class Event
    {
        #region Constants
        
        const double PIx = Math.PI;

        #endregion

        #region Properties
        [DataMember]
        public int ID { get; set; }

        [DataType(DataType.Text)]
        [Display(Name = "Event Name")]
        [DataMember]
        public string Name { get; set; }

        [DataType(DataType.Date)]
        [Display(Name = "StartTime")]
        [DataMember]
        public DateTime StartTime { get; set; } 

        [DataType(DataType.Date)]
        [Display(Name = "EndTime")]
        [DataMember]
        public DateTime EndTime { get; set; }

        [Display(Name = "LocationLatitude")]
        [DataMember]
        public double LocationLatitude { get; set; }

        [Display(Name = "LocationLongitude")]
        [DataMember]
        public double LocationLongitude { get; set; }

        [Display(Name = "LocationRadius")]
        [DataMember]
        public double LocationRadius { get; set; }//in km

        [DataType(DataType.Url)]
        [Display(Name = "Link")]
        [DataMember]
        public string Link;
        #endregion

        #region Conctructor
        
        public Event()
        {
        }

        public Event(int id, string name, DateTime start, DateTime end, double lat, double lon, double rad,string link)
        {
            this.ID = id;
            this.Name = name;
            this.StartTime = start;
            this.EndTime = end;
            this.LocationLatitude = lat;
            this.LocationLongitude = lon;
            this.LocationRadius = rad;
            this.Link = link;
        }

        #endregion

        #region Public Methos

        public double Radians(double x)
        {
            return x * PIx / 180.0;
        }

        private double RadianToDegree(double angle)
        {
            return Math.Cos(Radians(45)) * (180.0 / Math.PI);
        }


        public double DistanceBetweenPlaces(GeoLocation e2)
        { 
            double R = 6371; // km

            double sLat1 = Math.Sin(Radians(this.LocationLatitude));
            double sLat2 = Math.Sin(Radians(e2.LocationLatitude));
            double cLat1 = Math.Cos(Radians(this.LocationLatitude));
            double cLat2 = Math.Cos(Radians(e2.LocationLatitude));
            double cLon = Math.Cos(Radians(this.LocationLongitude) - Radians(e2.LocationLongitude));

            double cosD = sLat1 * sLat2 + cLat1 * cLat2 * cLon;

            double d = Math.Acos(cosD);

            double dist = R * d;

            return dist;
        }

        public GeoLocation MiddlePointBetweenPlaces(GeoLocation e2)
        {
             double dLon = Radians(e2.LocationLongitude - this.LocationLongitude);

            //convert to radians
            double lat1 = Radians(this.LocationLatitude);
            double lat2 = Radians(e2.LocationLatitude);
            double lon1 = Radians(this.LocationLongitude);

            double Bx = Math.Cos(lat2) * Math.Cos(dLon);
            double By = Math.Cos(lat2) * Math.Sin(dLon);
            double latMid = Math.Atan2(Math.Sin(lat1) + Math.Sin(lat2), Math.Sqrt((Math.Cos(lat1) + Bx) * (Math.Cos(lat1) + Bx) + By * By));
            double lonMid = lon1 + Math.Atan2(By, Math.Cos(lat1) + Bx);

            return new GeoLocation(RadianToDegree(lonMid), RadianToDegree(latMid));
        }

        public bool isRelevantTimeEvent()
        {
            DateTime currentDate = DateTime.Now;
            if (currentDate >= StartTime && currentDate <= EndTime)
                return true;
            return false;
        }

        #endregion
    }
}